import json
import os
import time
import subprocess
from datetime import datetime


class HttpGenerator:
    def __init__(self, num_principle=3, threshold=6):
        self.num_principle = num_principle
        self.threshold = threshold
        self.http_config = self.load_http_config()
        self.prompt_data = self.generate_prompt()

        if 'payload' not in self.http_config:
            self.http_config['payload'] = {}
        payload = self.http_config['payload']
        if 'messages' not in payload or not isinstance(payload['messages'], list):
            payload['messages'] = []

        if len(payload['messages']) == 0:
            payload['messages'].append({"role": "user", "content": ""})

        payload['messages'][0]["content"] = self.prompt_data

        output_path = os.path.join(os.path.dirname(__file__), 'output')
        os.makedirs(output_path, exist_ok=True)
        self.result_file = os.path.join(output_path, f'result_{datetime.now().strftime("%Y%m%d_%H%M%S")}.txt')

    def load_http_config(self):
        current_dir = os.path.dirname(__file__)
        config_path = os.path.join(current_dir, "http_config.json")
        try:
            with open(config_path, 'r', encoding='utf-8') as file:
                config = json.load(file)

            if not isinstance(config, dict):
                raise ValueError("配置文件格式错误，应为JSON对象")

            if not config.get('url'):
                raise ValueError("Missing API URL in config")

            if 'payload' not in config:
                config['payload'] = {}

            if not config['payload'].get('model'):
                raise ValueError("Missing model in config")

            return config
        except Exception as e:
            print(f"[ERROR] 加载配置失败: {str(e)}")
            raise

    def generate_prompt(self):
        initial_prompt_path = "initial_prompt.txt"
        cot_path = "cot.txt"
        role = "你是一个分析思维链的分析师，以下是一个模型关于金融风控场景的思维链，这个思维链结合了企业定性及定量的特征数据对企业风险进行多维度的评估。你要对下列思维链从以下几个角度进行评估："
        prompt = "\n 以下是原回答的提示词：\n"
        cot = "\n 以下是原回答的思维链：\n"
        with open("analysis_prompt2.0.txt", 'r', encoding='utf-8') as file:
            role += file.read()
        with open(cot_path, 'r', encoding='utf-8') as file:
            cot += file.read()
        with open(initial_prompt_path, 'r', encoding='utf-8') as file:
            prompt += file.read()
        final_prompt = role + cot + prompt
        return final_prompt

    def send_request(self):
        max_retries = 3
        backoff_factor = 1.5

        for attempt in range(max_retries):
            try:
                payload = json.dumps(self.http_config['payload'], ensure_ascii=False)
                curl_cmd = [
                    'curl', '-X', 'POST',
                    self.http_config['url'],
                    '-H', f"Content-Type: {self.http_config['headers']['Content-Type']}",
                    '-d', payload
                ]
                print(curl_cmd)

                # 执行命令时指定编码
                result = subprocess.run(
                    curl_cmd,
                    stdout=subprocess.PIPE,
                    stderr=subprocess.PIPE,
                    timeout=60,
                    check=True,
                    encoding='utf-8',
                )

                try:
                    response = json.loads(result.stdout)
                except json.JSONDecodeError as e:
                    print(f"[ERROR] JSON解析失败: {str(e)}")
                    print(f"原始响应内容:\n{result.stdout}")
                    raise

                # 安全获取content
                content = response.get('choices', [{}])[0].get('message', {}).get('content', '')
                if not content:
                    raise ValueError("生成内容为空")

                self._save_result(content)
                return content

            except subprocess.CalledProcessError as e:
                print(f"[ERROR] CURL命令执行失败（代码 {e.returncode}）: {e.stderr}")
                if attempt < max_retries - 1:
                    sleep_time = backoff_factor ** attempt
                    print(f"[INFO] {sleep_time:.1f}秒后重试...")
                    time.sleep(sleep_time)
                else:
                    print("[ERROR] 已达最大重试次数")
                    raise
            except Exception as e:
                print(f"[ERROR] 请求失败: {str(e)}")
                if 'result' in locals():
                    print(f"原始错误输出:\n{result.stderr}")
                raise

    def _save_result(self, content):
        try:
            with open(self.result_file, 'a', encoding='utf-8', errors='ignore') as f:
                f.write(f"[{datetime.now().isoformat()}] Generated content:\n")
                f.write(content + "\n\n")
            print(f"[INFO] 结果已保存至 {self.result_file}")
        except Exception as e:
            print(f"[ERROR] 保存失败: {str(e)}")

